`timescale 1ns / 1ps
//////////////////////////////////////////////////////////////////////////////////
// Company: 
// Engineer: 
// 
// Create Date: 2023/03/24 15:08:36
// Design Name: 
// Module Name: TimeSync
// Project Name: 
// Target Devices: 
// Tool Versions: 
// Description: 
// 
// Dependencies: 
// 
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
// 
//////////////////////////////////////////////////////////////////////////////////


module TimeSync(
    input sys_clk,
    input ADC_CLK,
    input rst_n,
    input [31:0] control_offset,
    output PPS_ref,
    output PPS_local,
    output PPS_ref_out,
    output PPS_local_out
    );

reg [31:0] 	control_offset_reg;
reg [31:0]	Integer_cycle;
reg [5:0]	VCO_Phase;
reg shift_start;

// 判断输入值是否发生变化，发生变化后锁存。每次输入时flag部分都将变化，触发锁存
// {[31:7],        	[6], 	  [5:0]}
// {Integer_cycle, flag,  VCO_Phase}
always @(posedge sys_clk or negedge rst_n) begin
	if (!rst_n) begin
		// reset
		control_offset_reg	<= 32'd0;
		Integer_cycle		<= 32'd0;
		VCO_Phase			<= 6'd0;
	end
	else if (control_offset_reg!=control_offset) begin
		control_offset_reg	<= control_offset;
		VCO_Phase			<= control_offset[5:0];
		// 把control_offset[31:7]的25bit扩展成32bit
		if(control_offset[31]==1'b1)
			Integer_cycle	<= Integer_cycle + {7'b1111111, control_offset[31:7]};
		else begin
			Integer_cycle	<= Integer_cycle + {7'b0000000, control_offset[31:7]};
		end
	end
	else begin
		control_offset_reg	<= control_offset_reg;
		Integer_cycle		<= Integer_cycle;
		VCO_Phase			<= VCO_Phase;
	end
end


always @(posedge sys_clk or negedge rst_n) begin
    if(!rst_n)
        shift_start <= 1'b0;
    else if(shift_start == 1'b1)
        shift_start <= 1'b0;
    else if(control_offset_reg != control_offset)
        shift_start <= 1'b1;
    else 
        shift_start <= shift_start;
end

wire clk_out1;
wire clk_out2;
ADC_count ADC_count_inst(
	.sys_clk(sys_clk),
    .ADC_CLK(ADC_CLK),
    .rst_n(rst_n),
    .shift_cnt(VCO_Phase),
    .shift_start(shift_start),
    .clk_out1(clk_out1),
    .clk_out2(clk_out2)
    );

reg [31:0] cnt1;
reg [31:0] cnt2;
localparam samplerate = 20000000;
localparam PPS_Width = 100;
// 每秒钟置零一次
always @(posedge clk_out1 or negedge rst_n) begin
	if (!rst_n) begin
		cnt1	<= 32'd0;
	end else if(cnt1==samplerate-1) begin
		cnt1	<= 32'd0;
	end else begin
		cnt1	<= cnt1 + 1'b1;
	end
end

always @(posedge clk_out2 or negedge rst_n) begin
	if (!rst_n) begin
		cnt2	<= 32'd0;
	end else if(cnt2==samplerate-1) begin
		cnt2	<= 32'd0;
	end else begin
		cnt2	<= cnt2 + 1'b1;
	end
end

reg PPS1;
reg PPS2;
always @(posedge clk_out1 or negedge rst_n) begin
	if (!rst_n) begin
		PPS1	<= 1'b0;
	end else if(cnt1>32'd10000000 &&  cnt1<=(32'd10000000+PPS_Width) ) begin
		PPS1	<= 1'b1;
	end else begin
		PPS1	<= 1'b0;
	end
end

always @(posedge clk_out2 or negedge rst_n) begin
	if (!rst_n) begin
		PPS2	<= 1'b0;
	end else if((Integer_cycle+PPS_Width <samplerate && cnt2>Integer_cycle &&  cnt2<=Integer_cycle+PPS_Width) || (Integer_cycle+PPS_Width >samplerate && (cnt2>Integer_cycle || cnt2<PPS_Width-samplerate+Integer_cycle)) ) begin
		PPS2	<= 1'b1;
	end else begin
		PPS2	<= 1'b0;
	end
end

reg PPS1_OUT;
reg PPS2_OUT;
always @(posedge clk_out1) begin
	PPS1_OUT	<= PPS1;
end
always @(posedge clk_out2) begin
	PPS2_OUT	<= PPS2;
end

assign PPS_ref = PPS1;
assign PPS_local = PPS2;
assign PPS_ref_out = PPS1_OUT;
assign PPS_local_out = PPS2_OUT;



(*mark_debug = "FALSE"*)(* KEEP = "FALSE" *) wire [31:0]cnt1;
(*mark_debug = "FALSE"*)(* KEEP = "FALSE" *) wire [31:0]cnt2;
(*mark_debug = "FALSE"*)(* KEEP = "FALSE" *) wire [31:0]Integer_cycle;


endmodule